#!/usr/bin/perl
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2016, Intel Corporation

#
# sort_solution -- sort visual studio solution projects lists
#

use strict;
use warnings;
# install libtext-diff-perl or perl-Text-Diff
use Text::Diff;

use Cwd 'abs_path';
use File::Basename;
use File::Compare;


sub help {
	print "Usage: sort_solution [check|sort]\n";
	exit;
}

sub sort_global_section {
	my ($solution_fh, $temp_fh, $section_name) = @_;
	my $line = "";
	my @array;

	while (defined($line = <$solution_fh>) && ($line !~ $section_name)) {
		print $temp_fh $line;
	}
	print $temp_fh $line;

	while (defined($line = <$solution_fh>) && ($line !~ "EndGlobalSection")) {
		push @array, $line;
	}

	@array = sort @array;

	foreach (@array) {
		print $temp_fh $_;
	}

	print $temp_fh $line; # print EndGlobalSection line
}

my $num_args = $#ARGV + 1;
if ($num_args != 1) {
	help;
}
my $arg = $ARGV[0];

if($arg ne "check" && $arg ne "sort") {
	help;
}
my $filename = dirname(abs_path($0)).'/../src/PMDK.sln';
my $tempfile = dirname(abs_path($0)).'/../src/temp.sln';

open(my $temp_fh, '>', $tempfile)
	or die "Could not open file '$tempfile' $!";
open(my $solution_fh, '<:crlf', $filename)
	or die "Could not open file '$filename' $!";

my $line;

# Read a header of file
while (defined($line = <$solution_fh>) && ($line !~ "^Project")) {
	print $temp_fh $line;
}

my @part1;
my $buff;
my $guid;

# Read the projects list with project dependencies
do {
	if($line =~ "^Project") {
		$buff = $line;
		$guid = (split(/\,/, $line))[2];
	} elsif($line =~ "^EndProject") {
		$buff .= $line;
		my %table = (
			guid => $guid,
			buff => $buff,
		);
		push @part1, \%table;
	} else {
		$buff .= $line;
	}

} while (defined($line = <$solution_fh>) && $line ne "Global\n");

# sort the project list by a project GIUD and write to the tempfile
@part1 = sort { $a->{guid} cmp $b->{guid} } @part1;

foreach (@part1) {
	my %hash = %$_;
	print $temp_fh $hash{"buff"};
}
print $temp_fh $line; # EndProject line

sort_global_section $solution_fh, $temp_fh, "ProjectConfigurationPlatforms";

sort_global_section $solution_fh, $temp_fh, "NestedProjects";

# read solution file to the end and copy it to the temp file
while (defined($line = <$solution_fh>)){
	print $temp_fh $line;
}

close($temp_fh);
close($solution_fh);

if($arg eq "check") {
	my $diff = diff $filename => $tempfile;
	if ($diff eq "") {
		unlink $tempfile;
		exit;
	}

	print "PMDK solution file is not sorted, " .
		"please use sort_solution script before pushing your changes\n";
	unlink $tempfile;
	exit 1;
} else {
	unlink $filename or die "Cannot replace solution file $!";
	rename $tempfile, $filename;
}
